﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.MobileControls;
using System.Threading;

namespace IronSharePoint.Fields
{
    public class IronFieldText : SPFieldText
    {
        protected IronScriptEngine engine;

        public IronFieldText(SPFieldCollection fields, string fieldName)
            :base(fields, fieldName)
        {
           
        }

        public IronFieldText(SPFieldCollection fields, string fieldName, string displayName)
            : base(fields, fieldName, displayName)
        {
            
        }

        private string _scriptPath;

        public string ScriptPath 
        {
            get
            {
                return base.GetCustomProperty("ScriptPath").ToString();
            }
            set
            {
                base.SetCustomProperty("ScriptPath", value);
                SetNamedSlot("ScriptPath", value);
            }
        }

        public void SetNamedSlot(string name, object value)
        {
            Thread.SetData(Thread.GetNamedDataSlot(name),value);
        }

        public object GetNamedSlotData(string name)
        {
            return Thread.GetData(Thread.GetNamedDataSlot(name));
        }

        public void ClearNamedSlot(string name)
        {
            Thread.FreeNamedDataSlot(name);
        }

        bool _preventUpdate=false;

        public override void OnAdded(SPAddFieldOptions op)
        {
           

            if (GetNamedSlotData("ScriptPath")!=null)
            {

                SetCustomProperty("ScriptPath", GetNamedSlotData("ScriptPath"));
                ClearNamedSlot("ScriptPath");
                _preventUpdate = true;
                Update();
                
                
            }

            EnsureScriptEngine();

            if (engine.Scope.ContainsVariable("OnAdded"))
            {
                object method = engine.Scope.GetVariable("OnAdded");
                engine.Operations.Call(method);
            }



            base.OnAdded(op);
        }

        public override void OnUpdated()
        {
            if (_preventUpdate == false)
            {
                _preventUpdate = true;
                ClearNamedSlot("ScriptPath");
            }

            EnsureScriptEngine();

            if (engine.Scope.ContainsVariable("OnUpdated"))
            {
                object method = engine.Scope.GetVariable("OnUpdated");
                engine.Operations.Call(method);
            }

            base.OnUpdated();
        }

        public override void OnDeleting()
        {
            EnsureScriptEngine();

            if (engine.Scope.ContainsVariable("OnDeleting"))
            {
                object method = engine.Scope.GetVariable("OnDeleting");
                engine.Operations.Call(method);
            }

            base.OnDeleting();
        }

        

        protected void EnsureScriptEngine()
        {
            if (engine == null)
            {
                engine = new IronScriptEngine();

                engine.ScriptResolver.FeatureId = Guid.Empty;
                engine.CompileScriptFrom(ScriptPath);

                engine.Scope.SetVariable("this", this);
            }
        }

        public override object GetFieldValue(string value)
        {
            EnsureScriptEngine();

            if (engine.Scope.ContainsVariable("GetFieldValue"))
            {
                object method = engine.Scope.GetVariable("GetFieldValue");
                return engine.Operations.Call(method, value);
            }
            else
            {
                return base.GetFieldValue(value);
            }
        }

        public override string GetValidatedString(object value)
        {
            EnsureScriptEngine();

            if (engine.Scope.ContainsVariable("GetValidatedString"))
            {
                object method = engine.Scope.GetVariable("GetValidatedString");
                return engine.Operations.Call(method) as String;
            }
            else
            {
                return base.GetValidatedString(value);
            }
            
        }

        public override BaseFieldControl FieldRenderingControl
        {
            get
            {
                EnsureScriptEngine();

                if (engine.Scope.ContainsVariable("FieldRenderingControl"))
                {
                    object method = engine.Scope.GetVariable("FieldRenderingControl");
                    return engine.Operations.Call(method) as BaseFieldControl;
                }
                else
                {
                    return base.FieldRenderingControl;
                }
                
            }
        }

        public override Microsoft.SharePoint.MobileControls.SPMobileBaseFieldControl FieldRenderingMobileControl
        {
            get
            {
                EnsureScriptEngine();

                return base.FieldRenderingMobileControl;
            }
        }

        public override Type FieldValueType
        {
            get
            {
                EnsureScriptEngine();

                if (engine.Scope.ContainsVariable("FieldValueType"))
                {
                    object method = engine.Scope.GetVariable("FieldValueType");
                    return engine.Operations.Call(method) as Type;
                }
                else
                {
                    return base.FieldValueType;
                }
                
            }
        }
 
    }
}
